home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir24
/
psi110g.zip
/
PATHNAME.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-17
|
6KB
|
210 lines
/* Convert relative to absolute pathnames
* Copyright 1991 Phil Karn, KA9Q
*/
#include "global.h"
#include "dirutil.h"
#include "config.h"
#include "index.h"
#ifdef CALLSERVER
#include <string.h>
extern char *CDROM; /* buckbook.c: defines CDROM drive letter e.g. "s:" */
#endif
void crunch __ARGS((char *buf,char *path));
static char* getroot __ARGS((char *buf,char *path));
/* Given a working directory and an arbitrary pathname, resolve them into
* an absolute pathname. Memory is allocated for the result, which
* the caller must free
*/
char *
pathname(cd,path)
char *cd; /* Current working directory */
char *path; /* Pathname argument */
{
char *buf;
#ifdef MSDOS
char *cp,c;
int tflag = 0;
#endif
#ifdef CALLSERVER
int drive = 0; /* is there a drive spec to preserve? */
#endif
if(cd == NULLCHAR || path == NULLCHAR)
return NULLCHAR;
#ifdef MSDOS
/* If path has any backslashes, make a local copy with them
* translated into forward slashes
*/
if(strchr(path,'\\') != NULLCHAR){
tflag = 1;
cp = path = strdup(path);
while(*cp) {
if(*cp == '\\')
*cp = '/';
cp++;
}
cp = path;
}
#endif
/* Strip any leading white space on args */
cd = skipwhite(cd);
path = skipwhite(path);
if(*path == '\0')
return strdup(cd);
#ifdef CALLSERVER
if (CDROM != NULLCHAR) {
if(!strncmp(path, CDROM, 2)) {
buf = strdup(path);
return buf;
}
if(!strncmp(cd, CDROM, 2))
drive = 1; /* make a note */
}
#endif
/* Allocate and initialize output buffer; user must free */
buf = mallocw((unsigned)strlen(cd) + strlen(path) + 10); /* fudge factor */
buf[0] = '\0';
/* Interpret path relative to cd only if it doesn't begin with "/"
* or doesn't have a drive letter indicator */
if((path[0] != '/') || (strlen(path) > 1 && path[1] != ':'))
crunch(buf,cd);
#ifdef CALLSERVER
else
drive = 0;
#endif
crunch(buf,path);
/* Special case: null final path means the root directory */
if(buf[0] == '\0'){
buf[0] = '/';
buf[1] = '\0';
}
#ifdef MSDOS
else if(buf[1] == ':' && buf[2] == '\0'){
buf[2] = '/';
buf[3] = '\0';
}
if(tflag)
free(path);
#endif
#ifdef CALLSERVER
if (drive) {
cp = buf;
while(*cp != '\0')
*cp = *(cp++ + 1);
}
#endif
return buf;
}
/* Process a path name string, starting with and adding to
* the existing buffer
*/
void
crunch(buf,path)
char *buf;
char *path;
{
char *cp;
#ifdef MSDOS
path=getroot(buf,path); /* for a case drive is specified */
if(buf[0] != '\0' && buf[1] == ':')
buf+=2; /* don't allow drive to be removed by '..' */
#endif
cp = buf + strlen(buf); /* Start write at end of current buffer */
/* Now start crunching the pathname argument */
for(;;){
/* Strip leading /'s; one will be written later */
while(*path == '/')
path++;
if(*path == '\0')
break; /* no more, all done */
/* Look for parent directory references, either at the end
* of the path or imbedded in it
*/
if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
/* Hop up a level */
if((cp = strrchr(buf,'/')) == NULLCHAR)
cp = buf; /* Don't back up beyond root */
*cp = '\0'; /* In case there's another .. */
path += 2; /* Skip ".." */
while(*path == '/') /* Skip one or more slashes */
path++;
/* Look for current directory references, either at the end
* of the path or imbedded in it
*/
} else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
/* "no op" */
path++; /* Skip "." */
while(*path == '/') /* Skip one or more slashes */
path++;
} else {
/* Ordinary name, copy up to next '/' or end of path */
*cp++ = '/';
while(*path != '/' && *path != '\0')
*cp++ = *path++;
}
}
*cp++ = '\0';
}
/* Get the first path out of the path from ftpusers, and
* allocate a new string for it. Caller should free this!
*/
char *firstpath(char *path) {
char *cp;
int len;
len = strcspn(path,"; \t"); /* Find length */
cp = mallocw(len+1); /* and copy it into new buffer */
memcpy(cp,path,len);
*(cp+len) = '\0';
return cp;
}
#ifdef MSDOS
/* If path specifies drive (e.g. A:), set buf to root on the drive
* and return path without drive specification, otherwise return path
* in any case remove leading / from path and set root if any found -jt
*/
static char*
getroot(buf,path)
char *buf,*path;
{
int root=0;
if(path[0] != '\0' && path[1] == ':') {
*buf++=*path++;
*buf++=*path++;
root=1;
/* Question here: what to do if drive specified
* is same as default ? Go to root directory or remain in
* current ? Currently goes to the root.
*/
}
/* Skip all leading '/' */
while(*path == '/') {
path++;
root=1;
}
if(root) {
if(buf[0] != '\0' && buf[1] == ':')
buf+=2; /* leave drive if set earlier */
buf[0]='\0';
}
return path;
}
#endif /* MSDOS */